package com.sinodata.bsm.center.web.action.appview;

import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;

import com.sinodata.bsm.center.bean.RelationHelper;
import com.sinodata.bsm.center.bean.ResBean;
import com.sinodata.bsm.center.cache.*;
import com.sinodata.bsm.center.service.config.APPService;
import com.sinodata.bsm.center.service.probe.ProbeService;
import com.sinodata.bsm.center.service.relation.ResRelationService;
import com.sinodata.bsm.center.service.resource.ResGroupService;
import com.sinodata.bsm.center.service.resource.ResService;
import com.sinodata.bsm.center.util.spring.SpringContextHolder;
import com.sinodata.bsm.center.util.web.Struts2Utils;
import com.sinodata.bsm.center.web.action.BaseAction;
import com.sinodata.bsm.common.constants.*;
import com.sinodata.bsm.common.vo.*;
import com.sinodata.bsm.center.cache.NewEventCache;

/**
 * @author fanshengchao
 *
 */
public class AppAction extends BaseAction<Res> {
    private static final long serialVersionUID = 1L;
    private Long id;
    private Res entity;

    @Autowired
    private ResService resService;
    @Autowired
    private ProbeService probeService;
    @Autowired
    private TopuConfCache topuConfCache;
    @Autowired
    private ResGroupService resGroupService;
    @Autowired
    private ResRelationService resRelationService;
    @Autowired
    private APPService appService;
    @Autowired
    private NewEventCache newEventCache;

    @Autowired
    protected ResGroupCache resGroupCache;
    @Autowired
    private RelationTypeCache relationTypeCache;
    @Autowired
    private MotiResRelCache motiResRelCache;
    @Autowired
    private PropertyValueCache propertyValueCache;
    private static final Long APP_RES_TYPEID = 1105050000000L;

    @Override
    public String delete() throws Exception {
        appService.delete(Long.valueOf(request.getParameter("id")));
        return null;
    }

    @Override
    public String input() throws Exception {

        List<Probe> probeList = probeService.findAllCicpProbe();
        Collections.sort(probeList, new Comparator<Probe>() {
            @Override
            public int compare(Probe o1, Probe o2) {
                Probe res1 = o1;
                Probe res2 = o2;
                if (Math.abs(res1.getStatus() - 3) > Math.abs(res2.getStatus() - 3)) {
                    return 1;
                } else {
                    return 0;
                }

            }

        });
        List<Res> appList = resService.findByResTypeId(APP_RES_TYPEID);
        request.setAttribute("appList", appList);
        Struts2Utils.getRequest().setAttribute("probeList", probeList);
        return "input";
    }

    public String initUpdate() throws Exception {
        String resId = request.getParameter("id");
        entity = resService.get(Long.parseLong(resId));
        List<Res> appList = resService.findByResTypeId(APP_RES_TYPEID);
        List<Long> startIds = resRelationService.getResByEndId(entity.getId(), RelationConstants.CONNECT);
        List<Res> startResList = new ArrayList<Res>();
        Res startRes = null;
        for (Long start : startIds) {
            if ((startRes = resService.get(start)) != null) {
                startResList.add(startRes);
            }
        }
        request.setAttribute("startResList", startResList);
        request.setAttribute("appList", appList);
        request.setAttribute("res", entity);
        return "update";
    }

    public String update() throws Exception {
        String resId = request.getParameter("id");
        entity = resService.get(Long.parseLong(resId));
        String name = request.getParameter("name");
        entity.setName(name);
        String[] idArr = request.getParameterValues("resRelation");

        List<ResRelation> list = resRelationService.getResRelationsOfRes(entity.getId());
        List<ResRelation> deleteList = new ArrayList<ResRelation>();
        if (list != null) {
            for (ResRelation rel : list) {
                if (rel.getEndId().equals(entity.getId()) && rel.getRelationTypeId().equals(RelationConstants.CONNECT)) {
                    deleteList.add(rel);
                }
            }
        }
        for (int i = deleteList.size() - 1; i >= 0; i--) {
            resRelationService.removeResRelation(deleteList.get(i));
        }
        if (idArr != null) {
            for (String id : idArr) {
                ResRelation rel = new ResRelation();
                rel.setStartId(Long.parseLong(id));
                rel.setEndId(entity.getId());
                rel.setRelationTypeId(RelationConstants.CONNECT);
                resRelationService.addResRelation(rel);
            }
        }
        return null;
    }

    @Override
    public String list() throws Exception {
        return null;
    }

    @Override
    protected void prepareModel() throws Exception {
        if (id == null) {
            entity = new Res();
        } else {
            entity = resService.get(id);
        }

    }

    @Override
    public String save() throws Exception {
        try {

            entity.setHealthStatus(ResConstants.NORMAL_USABLE);
            entity.setPaused(ResConstants.RES_NOT_PAUSED);
            entity.setResTypeId(APP_RES_TYPEID);
            resService.addTopResource(null, entity, new ArrayList<ResAttrVal>(0));
            resGroupService.saveApplicationGroup(entity.getId());
            String[] idArr = request.getParameterValues("resRelation");
            if (idArr != null) {
                for (String id : idArr) {
                    ResRelation rel = new ResRelation();
                    rel.setStartId(Long.parseLong(id));
                    rel.setEndId(entity.getId());
                    rel.setRelationTypeId(RelationConstants.CONNECT);
                    resRelationService.addResRelation(rel);
                }
            }
            Struts2Utils.renderJson(entity);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public String initView() throws Exception {
        Map<Long, Integer[]> map = new HashMap<Long, Integer[]>();

        Set<Long> resIds = newEventCache.getEventRes();
        List<Res> appList = resService.findByResTypeId(APP_RES_TYPEID);
        Map<Long, Long[]> rootIds = new HashMap<Long, Long[]>();
        Map<Long, Integer[]> useabalityMap = new HashMap<Long, Integer[]>();
        for (Res app : appList) {
            List<ResGroup> groups = resGroupCache.findByResId(app.getId().longValue());
            if (groups != null) {
                for (ResGroup group : groups) {
                    Long ctype = group.getContainType();
                    if (ctype == null) {
                        continue;
                    }
                    long type = 0;
                    List<MotiResRel> rootList = motiResRelCache.findByResGroupId(group.getId());
                    if (ctype >= 2000L && ctype < 3000L) {
                        //则代表是基础资源的根资源
                        type = 1L;
                    } else if (ctype > 1000L && ctype < 2000L) {
                        //应用环境类
                        type = 2L;
                    } else if (ctype <= 100L) {
                        //接口类
                        type = 3L;
                    } else if (ctype == 1000L) {
                        //应用服务
                        int usedCount = 0;
                        int unusedCount = 0;
                        for (int i = 0; rootList != null && i < rootList.size(); i++) {
                            String status = propertyValueCache.getValue(rootList.get(i).getResId(), 110506000000002L);
                            //String timeStr = propertyValueCache.getValue(rootList.get(i).getResId(), 110506000000001L); 
                            if (status != null && status.trim().equals("1")) {
                                usedCount++;
                            } else {
                                unusedCount++;
                            }
                        }
                        useabalityMap.put(app.getId(), new Integer[] { usedCount, unusedCount });
                        continue;
                    }
                    for (int i = 0; rootList != null && i < rootList.size(); i++) {
                        rootIds.put(rootList.get(i).getResId(), new Long[] { app.getId(), type });
                    }
                }
            }
            List<Long> startIds = resRelationService.getResByEndId(app.getId(), RelationConstants.CONNECT);
            int parentCount = 0;
            for (Long startId : startIds) {
                Res pres = resService.get(startId);
                if (pres != null && pres.getHealthStatus() > 1) {
                    parentCount++;
                }
            }
            map.put(app.getId(), new Integer[] { parentCount, 0, 0, 0 });
        }
        Set<Long> relationTypeIds = resRelationService.getSelfAndSubRelationTypeIds();
        for (Long resId : resIds) {
            Res res = resService.get(resId);
            if (res != null) {
                Long[] val = getAppRes(res, relationTypeIds, rootIds);
                if (val != null) {
                    long appId = val[0];
                    Long type = val[1];
                    Integer[] counters = map.get(appId);
                    int old = counters[type.intValue()];
                    List events = newEventCache.getNewEventsByResId(res.getId());
                    int size = events != null ? events.size() : 0;
                    counters[type.intValue()] = old + size;
                }
            }
        }

        request.setAttribute("appList", appList);
        request.setAttribute("events", map);
        request.setAttribute("useabalityMap", useabalityMap);
        return "viewmain";
    }

    private Long[] getAppRes(Res child, Set<Long> relationTypeIds, Map<Long, Long[]> rootIds) {
        if (rootIds.containsKey(child.getId().longValue())) {
            //则此res是某个应用下的资源
            return rootIds.get(child.getId().longValue());
        }
        List<ResBean> parents = RelationHelper.from(child.getId(), relationTypeIds);
        for (ResBean resbean : parents) {
            Res res = resbean.res();
            Long[] val = getAppRes(res, relationTypeIds, rootIds);
            if (val == null) {
                continue;
            }
            return val;
        }
        return null;
    }

    @Override
    public Res getModel() {
        return entity;
    }

    public String add() {
        Res res = resService.get(Long.valueOf(request.getParameter("resId")));
        List<TopuConf> topuConfList = topuConfCache.findAll();
        Struts2Utils.getRequest().setAttribute("res", res);
        Struts2Utils.getRequest().setAttribute("topuConfList", topuConfList);
        return "add";
    }

    public String addDo() {
        Long resId = Long.valueOf(request.getParameter("resId"));
        Long type = Long.valueOf(request.getParameter("type"));
        String[] topuConfIds = request.getParameterValues("topo");
        if (topuConfIds != null && topuConfIds.length > 0) {
            for (String s : topuConfIds) {
                Long topuConfId = Long.valueOf(s);
                AppresTopoRel appResTopoRel = new AppresTopoRel(null, resId, type, topuConfId);
                appService.save(appResTopoRel);
            }
        }
        return null;
    }
}
